package org.dbrd.model;

import java.util.Set;

import org.dbrd.Config;
import org.dbrd.detector.tfidf.TFCollection;

public abstract class DetectionBugReport extends AbstractBugReport {

	/************************************************************************
	 * vectors for summary, (ugram, bigram, trigram)
	 ************************************************************************/
	// protected final String[] summaryVector;
	// protected final String[] bigramSummaryVector;
	// protected final List<String> trigramSummaryVector;
	/************************************************************************
	 * vectors for description, (ugram, bigram, trigram)
	 ************************************************************************/
	// protected final String[] descriptionVector;
	// protected final String[] bigramDescriptionVector;
	// protected final List<String> trigramDescriptionVector;
	/************************************************************************
	 * vectors for tf of summaries, (ugram, bigram, trigram)
	 ************************************************************************/
	protected final TFCollection summaryTFCollection;

	protected final TFCollection bigramSummaryTFCollection;

	protected final TFCollection trigramSummaryTFCollection;

	// protected final TFCollection trigramSummaryTFCollection;

	/************************************************************************
	 * vectors for tf of description, (ugram, bigram, trigram)
	 ************************************************************************/
	protected final TFCollection descriptionTFCollection;

	protected final TFCollection bigramDescriptionTFCollection;

	protected final TFCollection trigramDescriptionTFCollection;

	// protected final TFCollection trigramDescriptionTFCollection;

	/************************************************************************
	 * vectors for tf of description, (ugram, bigram, trigram)
	 ************************************************************************/
	protected final TFCollection totalTFCollection;

	protected final TFCollection bigramTotalCollection;

	protected final TFCollection trigramTotalCollection;

	// protected final TFCollection trigramTotalCollection;

	protected double similarity;

	public DetectionBugReport(int id, String originalSummary, String processedSummary, String originalDescription,
			String processedDescription, int duplicateId, final int priority, final String version, final String subComponent,
			final String issueType, String component) {
		super(id, originalSummary, processedSummary, originalDescription, processedDescription, duplicateId, priority, version,
				subComponent, issueType, component);
		this.summaryTFCollection = new TFCollection();
		this.bigramSummaryTFCollection = new TFCollection();
		// this.trigramSummaryTFCollection = new TFCollection();
		if (Config.IDENTIFYING_PROCESSING) {
			this.trigramSummaryTFCollection = new TFCollection();
		} else {
			this.trigramSummaryTFCollection = null;
		}

		this.descriptionTFCollection = new TFCollection();
		this.bigramDescriptionTFCollection = new TFCollection();
		// this.trigramDescriptionTFCollection = new TFCollection();
		if (Config.IDENTIFYING_PROCESSING) {
			this.trigramDescriptionTFCollection = new TFCollection();
		} else {
			this.trigramDescriptionTFCollection = null;
		}

		this.totalTFCollection = new TFCollection();
		this.bigramTotalCollection = new TFCollection();

		if (Config.IDENTIFYING_PROCESSING) {
			this.trigramTotalCollection = new TFCollection();
		} else {
			this.trigramTotalCollection = null;
		}

		String temp;

		String[] summaryVector = this.processedSummary.split("\\s+");
		// unigrams
		for (int i = 0; i < summaryVector.length; i++) {
			temp = summaryVector[i];
			this.summaryTFCollection.addTerm(temp);
			this.totalTFCollection.addTerm(temp);
		}
		// bigrams
		for (int i = 0; i < summaryVector.length - 1; i++) {
			temp = summaryVector[i] + " " + summaryVector[i + 1];
			this.bigramSummaryTFCollection.addTerm(temp);
			this.bigramTotalCollection.addTerm(temp);
		}

		if (Config.IDENTIFYING_PROCESSING) {
			// trigrams
			for (int i = 0; i < summaryVector.length - 2; i++) {
				temp = summaryVector[i] + " " + summaryVector[i + 1] + " " + summaryVector[i + 2];
				this.trigramSummaryTFCollection.addTerm(temp);
				this.trigramTotalCollection.addTerm(temp);
			}
		}

		// for (int i = 0; i < summaryVector.length - 1; i++) {
		// temp = summaryVector[i];
		// this.totalTFCollection.addTerm(temp);
		// this.summaryTFCollection.addTerm(temp);
		//
		// bigramTemp = temp + " " + summaryVector[i + 1];
		// this.bigramTotalCollection.addTerm(bigramTemp);
		// this.bigramSummaryTFCollection.addTerm(bigramTemp);
		// }
		// temp = summaryVector[summaryVector.length - 1];
		// this.totalTFCollection.addTerm(temp);
		// this.summaryTFCollection.addTerm(temp);

		summaryVector = null;

		String[] descriptionVector = this.processedDescription.split("\\s+");

		// unigrams
		for (int i = 0; i < descriptionVector.length; i++) {
			temp = descriptionVector[i];
			this.totalTFCollection.addTerm(temp);
			this.descriptionTFCollection.addTerm(temp);
		}

		// bigrams
		for (int i = 0; i < descriptionVector.length - 1; i++) {
			temp = descriptionVector[i] + " " + descriptionVector[i + 1];
			this.bigramDescriptionTFCollection.addTerm(temp);
			this.bigramTotalCollection.addTerm(temp);
		}

		// trigrams
		if (Config.IDENTIFYING_PROCESSING) {
			for (int i = 0; i < descriptionVector.length - 2; i++) {
				temp = descriptionVector[i] + " " + descriptionVector[i + 1] + " " + descriptionVector[i + 2];
				this.trigramDescriptionTFCollection.addTerm(temp);
				this.trigramTotalCollection.addTerm(temp);
			}
		}
		//
		// for (int i = 0; i < descriptionVector.length - 1; i++) {
		// temp = descriptionVector[i];
		// this.totalTFCollection.addTerm(temp);
		// this.descriptionTFCollection.addTerm(temp);
		//
		// bigramTemp = temp + " " + descriptionVector[i + 1];
		// this.bigramTotalCollection.addTerm(bigramTemp);
		// this.bigramDescriptionTFCollection.addTerm(bigramTemp);
		// }
		// temp = descriptionVector[descriptionVector.length - 1];
		// this.totalTFCollection.addTerm(temp);
		// this.descriptionTFCollection.addTerm(temp);
		// this.trigramTotalCollection = new TFCollection();
	}

	public double getSimilarity() {
		return similarity;
	}

	public TFCollection getSummaryTFCollection() {
		return summaryTFCollection;
	}

	public TFCollection getDescriptionTFCollection() {
		return descriptionTFCollection;
	}

	public TFCollection getTotalTFCollection() {
		return totalTFCollection;
	}

	public void setSimilarity(double similarity) {
		this.similarity = similarity;
	}

	/**
	 * this method will calculate three kinds of frequencies. one is for summary
	 * vector, one is for description vector and the last is for the total
	 * frequency
	 */

	// private void initializeTFCollection() {
	// this.summaryTFCollection.clear();
	// this.bigramSummaryTFCollection.clear();
	// // this.trigramSummaryTFCollection.clear();
	//
	// this.descriptionTFCollection.clear();
	// this.bigramDescriptionTFCollection.clear();
	// // this.trigramDescriptionTFCollection.clear();
	//
	// this.totalTFCollection.clear();
	// this.bigramTotalCollection.clear();
	// // this.trigramTotalCollection.clear();
	// }
	@Override
	public String getOriginalSummary() {
		return super.getOriginalSummary();
	}

	/**
	 * using getSummary() instread;
	 */
	@Override
	public String getProcessedSummary() {
		return super.getProcessedSummary();
	}

	public String[] getSummaryTerms() {
		return this.summaryTFCollection.getTerms();
	}

	public String[] getBigramSummaryTerms() {
		return this.bigramSummaryTFCollection.getTerms();
	}

	public String[] getTrigramSummaryTerms() {
		return this.trigramSummaryTFCollection.getTerms();
	}

	// public String[] getTrigramSummaryTerms() {
	// return this.trigramSummaryTFCollection.getTerms();
	// }

	public Set<String> getSummaryTermsSet() {
		return this.summaryTFCollection.getTermsSet();
	}

	public String[] getDescriptionTerms() {
		return this.descriptionTFCollection.getTerms();
	}

	public String[] getBigramDescriptionTerms() {
		return this.bigramDescriptionTFCollection.getTerms();
	}

	public String[] getTrigramDescriptionTerms() {
		return this.trigramDescriptionTFCollection.getTerms();
	}

	// public String[] getTrigramDescriptionTerms() {
	// return this.trigramDescriptionTFCollection.getTerms();
	// }

	public Set<String> getDescriptionTermsSet() {
		return this.descriptionTFCollection.getTermsSet();
	}

	public String[] getAllTerms() {
		return this.totalTFCollection.getTerms();
	}

	public String[] getBigramAllTerms() {
		return this.bigramTotalCollection.getTerms();
	}

	public String[] getTrigramAllTerms() {
		return this.trigramTotalCollection.getTerms();
	}

	// public String[] getTrigramAllTerms() {
	// return this.trigramTotalCollection.getTerms();
	// }

	public int getTFInSummary(String term) {
		return this.summaryTFCollection.getFrequency(term);
	}

	public int getBigramTFInSummary(String term) {
		return this.bigramSummaryTFCollection.getFrequency(term);
	}

	// public int getTrigramTFInSummary(String term) {
	// return this.trigramSummaryTFCollection.getFrequency(term);
	// }

	public int getCountOfTermsInSummary() {
		return this.summaryTFCollection.getTermCount();
	}

	public int getTotalCountOfTerms() {
		return this.totalTFCollection.getTermCount();
	}

	public int getCountOfTermsInDescription() {
		return this.descriptionTFCollection.getTermCount();
	}

	public int getTFInDescription(String term) {
		return this.descriptionTFCollection.getFrequency(term);
	}

	public TFCollection getBigramSummaryTFCollection() {
		return bigramSummaryTFCollection;
	}

	public TFCollection getTrigramSummaryTFCollection() {
		return trigramSummaryTFCollection;
	}

	public TFCollection getBigramDescriptionTFCollection() {
		return bigramDescriptionTFCollection;
	}

	public TFCollection getTrigramDescriptionTFCollection() {
		return trigramDescriptionTFCollection;
	}

	public TFCollection getBigramTotalCollection() {
		return bigramTotalCollection;
	}

	public TFCollection getTrigramTotalCollection() {
		return trigramTotalCollection;
	}

	public int getBigramTFInDescription(String term) {
		return this.bigramDescriptionTFCollection.getFrequency(term);
	}

	// public int getTrigramTFInDescription(String term) {
	// return this.trigramDescriptionTFCollection.getFrequency(term);
	// }

	public int getTotalTF(String term) {
		return this.totalTFCollection.getFrequency(term);
	}

	public int getBigramTotalTF(String term) {
		return this.bigramTotalCollection.getFrequency(term);
	}

	// public int getTrigramTotalTF(String term) {
	// return this.trigramTotalCollection.getFrequency(term);
	// }

	@Deprecated
	public double getProbability(String term) {
		return this.summaryTFCollection.getProbability(term);
	}

	/**
	 * this method will generate two vectors, one is for summary and the other
	 * is for description.
	 */
	// public void generateVector() {
	// this.generateWordVector();
	// this.generateBigramVector();
	// // this.generateTrigramVector();
	// }

	// private void generateWordVector() {
	// for (String string : this.processedSummary.split("\\s+")) {
	// this.summaryVector.add(string);
	// }
	// for (String string : this.processedDescription.split("\\s+")) {
	// this.descriptionVector.add(string);
	// }
	// if (Config.CHECKING
	// && (this.summaryVector.size() == 0 || this.descriptionVector.size() ==
	// 0)) {
	// throw new
	// RuntimeException("summary vector or description vector is empty. " +
	// this);
	// }
	// this.clearSummaryAndDescription();
	// }
	//
	// private void generateBigramVector() {
	// for (int i = 0; i < summaryVector.size() - 1; i++) {
	// this.bigramSummaryVector.add(summaryVector.get(i) + " " +
	// summaryVector.get(i + 1));
	// }
	//
	// for (int i = 0; i < descriptionVector.size() - 1; i++) {
	// this.bigramDescriptionVector.add(descriptionVector.get(i) + " "
	// + descriptionVector.get(i + 1));
	// }
	// }

	// private void generateTrigramVector() {
	// for (int i = 0; i < summaryVector.size() - 2; i++) {
	// this.trigramSummaryVector.add(summaryVector.get(i) + " " +
	// summaryVector.get(i + 1)
	// + " " + summaryVector.get(i + 2));
	// }
	// for (int i = 0; i < descriptionVector.size() - 2; i++) {
	// this.trigramDescriptionVector.add(descriptionVector.get(i) + " "
	// + descriptionVector.get(i + 1) + " " + descriptionVector.get(i + 2));
	// }
	// }

	// public String[] getWordVector() {
	// return this.wordVector.toArray(new String[this.wordVector.size()]);
	// }
	//
	// public String[] getBigramVector() {
	// return this.bigramVector.toArray(new String[this.bigramVector.size()]);
	// }
	//
	// public String[] getTrigramVector() {
	// return this.trigramVector.toArray(new String[this.trigramVector.size()]);
	// }

	@Deprecated
	public void appendSummaryAndCalculateTF(String summary) {
		// this.processedSummary = this.processedSummary + " " + summary;
		// this.generateVector();
		// this.calculateTermFrequency();
	}

	@Deprecated
	public DetectionBugReport copy() {
		// DetectionBugReport newOne = new DetectionBugReport(this.id,
		// this.originalSummary,
		// this.processedSummary, this.originalDescription,
		// this.processedDescription,
		// this.duplicateId);
		// newOne.summaryTFCollection = this.summaryTFCollection.copy();
		// newOne.descriptionTFCollection = this.descriptionTFCollection.copy();
		// newOne.totalTFCollection = this.totalTFCollection.copy();
		// // newOne.tfCollection = this.tfCollection.copy();
		// newOne.generateVector();
		// newOne.calculateTermFrequency();
		// return newOne;
		return null;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append(this.getClass().getSimpleName()).append("\n");
		builder.append("ID = ").append(this.id).append("\n");
		builder.append("OS = ").append(this.getOriginalSummary()).append("\n");
		builder.append("PS = ").append(this.getProcessedSummary()).append("\n");
		builder.append("OD = ").append(this.getOriginalDescription()).append("\n");
		builder.append("PD = ").append(this.getProcessedDescription()).append("\n");
		return builder.toString();
	}
}
